﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Xml.Linq;
using System.Data.SqlClient;
using System.Collections.Generic;

namespace QA_System
{
    public class action_move_define
    {
        private string _types;

        private string _content;

        public action_move_define()
        {
            _types = "";
            _content = "";
        }

        public action_move_define(string type_txt)
        {
            _types = type_txt;
            _content = "";
        }

        public action_move_define(string type_txt, string content_txt)
        {
            _types = type_txt;
            _content = content_txt;
        }

        public string get_types()
        {
           return _types;
        }

        public string get_content()
        {
            return _content;
        }

        public void set_type(string type_txt)
        {
            _types = type_txt;
        }
       
        public void set_content(string content_txt)
        {
            _content = content_txt;
        }
    }
    

    
    
    public class QA_issue
    {
         
        public static string extract_genre(string user_text)
        {
            string genre_name = "";
            string all_g = Genre.GetAllKindOfGenre();

            string[] all_g_list = all_g.Split('/');
            bool stop = false; int i = 0;
            while (stop == false)
            {
                if (user_text.Contains(all_g_list[i])) { genre_name = all_g_list[i]; stop = true; }
                else { i++; if (i == all_g_list.Length) stop = true; }
            }
            return genre_name;

        }

        public static string extract_material(string user_text)
        {
            string material = "";
            string all_m = Painting.GetAllMaterial();

            string[] all_m_list = all_m.Split('/');
            bool stop = false; int i = 0;
            while (stop == false)
            {
                if (user_text.Contains(all_m_list[i])) { material = all_m_list[i]; stop = true; }
                else { i++; if (i == all_m_list.Length) stop = true; }
            }
            return material;

        }
        
        public static string extract_N(string user_text)
        {

            string keyword_true = "";
            string extract = "";

            string[] keyword_string_array = user_text.Split(' ');
            bool stop = false; int i = keyword_string_array.Length - 1;

            // tim nguoc xau
            while (stop == false)
            {
                char[] charArr = keyword_string_array[i].ToCharArray();
                if ((charArr[0].ToString() == charArr[0].ToString().ToUpper()) && (!Char.IsDigit(charArr[0])))
                {
                    keyword_true += keyword_string_array[i] + " ";
                    i--;
                    if (i == -1) stop = true;
                }
                else
                {
                    if (keyword_true == "")
                    {
                        i--;
                        if (i == -1) stop = true;
                    }
                    else
                    { stop = true; }

                }
            }

            // dao lai xau
            string[] keyword_true_array = keyword_true.Split(' ');
            for (int k = (keyword_true_array.Length - 2); k >= 0; k--)
            {
                if (k != 0) extract += keyword_true_array[k] + " ";
                else extract += keyword_true_array[k];
            }
            return extract;
        }

        public static bool is_content(string root_string, string word_compare)
        {
            string[] root_mem = root_string.Split('/');
            bool content = false;
            int i = 0;
            while ((content == false) && (i < root_mem.Length))
            {
                if (root_mem[i].Contains(word_compare.ToUpper())) content = true;
                i++;
            }
            return content;
        }
        
        public static void interpret_user1(string user_text, ref string last_speaker, ref action_move_define last_move)
        {
            if (user_text != "")
            {
                if ((user_text.Contains("tạm biệt")) || (user_text.Contains("cảm ơn")))
                {
                    last_move.set_type("quit");
                    last_move.set_content("");
                }
                else
                {
                    if (((user_text.Contains("thông tin")) || (user_text.Contains("Thông tin"))) && (user_text.Contains("tranh")))
                    {
                        last_move.set_type("ask");
                        last_move.set_content("?.find_paint");
                        last_speaker = "usr";
                    }
                    else
                    {


                        if (((user_text.Contains("thông tin")) || (user_text.Contains("Thông tin"))) && ((user_text.Contains("tác giả")) || (user_text.Contains("họa sĩ"))))
                        {
                            last_move.set_type("ask");
                            last_move.set_content("?.find_art");
                            last_speaker = "usr";
                        }
                        else
                        {


                            string content_N = extract_N(user_text);
                            if (content_N != "")
                            {

                                if (QA_issue.is_content(Artist.GetAllArtName(), content_N))
                                {
                                    string content_txt = "?.artist." + content_N;
                                    last_move.set_type("answer");
                                    last_move.set_content(content_txt);
                                    last_speaker = "usr";
                                }
                                else
                                {
                                    if (QA_issue.is_content(Artist.GetAllNationality(), content_N))
                                    {
                                        string content_txt = "?.nationality." + content_N;
                                        last_move.set_type("answer");
                                        last_move.set_content(content_txt);
                                        last_speaker = "usr";
                                    }
                                    else
                                    {
                                        if (QA_issue.is_content(Painting.GetAllPaintName(), content_N))
                                        {
                                            string content_txt = "?.have_paint." + content_N;
                                            last_move.set_type("answer");
                                            last_move.set_content(content_txt);
                                            last_speaker = "usr";
                                        }

                                    }
                                }

                            }
                            else
                            {
                                string content_G = extract_genre(user_text);
                                if (content_G != "")
                                {
                                    string content_txt = "?.genre." + content_G;
                                    last_move.set_type("answer");
                                    last_move.set_content(content_txt);
                                    last_speaker = "usr";
                                }
                                else
                                {
                                    string content_M = extract_material(user_text);
                                    if (content_M != "")
                                    {
                                        string content_txt = "?.material." + content_M;
                                        last_move.set_type("answer");
                                        last_move.set_content(content_txt);
                                        last_speaker = "usr";
                                    }
                                    /*
                                    else
                                    {
                                        last_move.set_type("fail");
                                        last_move.set_content("");
                                        last_speaker = "usr";
                                    }
                                     */

                                }
                            }

                        }

                    }
                }
            }
        }

        public static void interpret_user(string user_text, ref string last_speaker, ref action_move_define last_move)
        {
            if (user_text != "")
            {
                if ((user_text.ToLower().Contains("tạm biệt")) || (user_text.ToLower().Contains("cảm ơn")) || (user_text.ToLower().Contains("gặp lại")))
                {
                    last_move.set_type("quit");
                    last_move.set_content("");
                    last_speaker = "usr";
                }
                else
                {
                    if ((user_text.ToLower().Contains("chào")) || (user_text.ToLower().Contains("hello")))
                    {
                        last_move.set_type("greet1");
                        last_move.set_content("");
                        last_speaker = "usr";
                    }
                    else
                    {
                        if ((user_text.ToLower().Contains("thông tin")) && (user_text.ToLower().Contains("tranh")))
                        {
                            last_move.set_type("ask");
                            last_move.set_content("?.find_paint");
                            last_speaker = "usr";
                        }
                        else
                        {

                            if ((user_text.ToLower().Contains("thông tin")) && ((user_text.ToLower().Contains("tác giả")) || (user_text.ToLower().Contains("họa sĩ"))))
                            {
                                last_move.set_type("ask");
                                last_move.set_content("?.find_art");
                                last_speaker = "usr";
                            }
                            else
                            {
                                if ((last_move.get_types() == "ask") && (last_speaker == "sys")&&(!user_text.Contains("?")))
                                {

                                    if (last_move.get_content().Contains("artist"))
                                    {
                                        string content_N = extract_N(user_text);
                                        string content_txt = "?.artist." + content_N;
                                        last_move.set_type("answer");
                                        last_move.set_content(content_txt);
                                        last_speaker = "usr";
                                    }
                                    else
                                    {
                                        if (last_move.get_content().Contains("nationality"))
                                        {
                                            string content_N = extract_N(user_text);
                                            string content_txt = "?.nationality." + content_N;
                                            last_move.set_type("answer");
                                            last_move.set_content(content_txt);
                                            last_speaker = "usr";
                                        }
                                        else
                                        {
                                            if (last_move.get_content().Contains("have_paint"))
                                            {
                                                string content_N = extract_N(user_text);
                                                string content_txt = "?.have_paint." + content_N;
                                                last_move.set_type("answer");
                                                last_move.set_content(content_txt);
                                                last_speaker = "usr";
                                            }
                                            else
                                            {
                                                if (last_move.get_content().Contains("genre"))
                                                {
                                                    string content_G = extract_genre(user_text);
                                                    string content_txt = "?.genre." + content_G;
                                                    last_move.set_type("answer");
                                                    last_move.set_content(content_txt);
                                                    last_speaker = "usr";

                                                }
                                                else
                                                {
                                                    if (last_move.get_content().Contains("material"))
                                                    {
                                                        string content_M = extract_material(user_text);
                                                        string content_txt = "?.material." + content_M;
                                                        last_move.set_type("answer");
                                                        last_move.set_content(content_txt);
                                                        last_speaker = "usr";
                                                    }

                                                }

                                            }

                                        }
                                    }

                                }

                            }
                        }
                    }
                }

                        }

                    }
                
        //không cần đến
        public static string interpret_sys(string sys_txt)
        {
            string interpret="";
            
            if (sys_txt.Contains("?"))
            {
                if (sys_txt.Contains("trường phái")) interpret = "ask.findout_genre";
                if (sys_txt.Contains("chất liệu")) interpret = "ask.raise_material";
                if (sys_txt.Contains("tác giả")) interpret = "ask.findout_artist";
                if (sys_txt.Contains("nước")) interpret = "ask.raise_nationality";
                if (sys_txt.Contains("tên")) interpret = "ask.findout_have_paint";
            }
            else
            {
                if (sys_txt.Contains("Chào")) interpret = "greet";
                else
                {
                    if (sys_txt.Contains("họa sĩ")) interpret = "answer.find_art";
                    else interpret = "answer.find_paint";
                }
                
            }
            if (interpret == "") interpret = "failed";
            return interpret;

        }
      

        public static bool relevant(string answer, string ask)
        {
            bool relevan = false;
            if ((ask != null) && (answer != null))
            {
                if ((ask.Contains("genre")) && (answer.Contains("genre"))) relevan = true;
                if ((ask.Contains("material")) && (answer.Contains("material"))) relevan = true;
                if ((ask.Contains("artist")) && (answer.Contains("artist"))) relevan = true;
                if ((ask.Contains("have_paint")) && (answer.Contains("have_paint"))) relevan = true;
                if ((ask.Contains("nationality")) && (answer.Contains("nationality"))) relevan = true;
                if ((ask.Contains("find_paint")) && (answer.Contains("paint_name"))) relevan = true;
                if ((ask.Contains("find_art")) && (answer.Contains("art_name"))) relevan = true;
                if ((ask.Contains("issue")) && ((answer.Contains("find_art")) || (answer.Contains("find_paint")))) relevan = true;
            }
            return relevan;
        }

        public static bool resolves(string answer, string ask)
        {
            bool resolve = false;
            if ((ask != null) && (answer != null))
            {
                if ((ask.Contains("genre")) && (answer.Contains("genre")) && (!answer.Contains("not")))
                {
                    string t = answer.Replace("?.genre.", "");
                    if (t.Equals("") == true) resolve = false;
                    else resolve = true;
                }

                if ((ask.Contains("material")) && (answer.Contains("material")) && (!answer.Contains("not")))
                {
                    string t = answer.Replace("?.material.", "");
                    if (t.Equals("") == true) resolve = false;
                    else resolve = true;
                }
                if ((ask.Contains("artist")) && (answer.Contains("artist")) && (!answer.Contains("not"))) 
                {
                    string t = answer.Replace("?.artist.", "");
                    if (t.Equals("") == true) resolve = false;
                    else resolve = true;
                }
                if ((ask.Contains("have_paint")) && (answer.Contains("have_paint")) && (!answer.Contains("not")))
                {
                    string t = answer.Replace("?.have_paint.", "");
                    if (t.Equals("") == true) resolve = false;
                    else resolve = true;
                }
                if ((ask.Contains("nationality")) && (answer.Contains("nationality")) && (!answer.Contains("not")))
                {

                    string t = answer.Replace("?.nationality.", "");
                    if (t.Equals("") == true) resolve = false;
                    else resolve = true;

                    //resolve = true;
                }
                if ((ask.Contains("find_paint")) && (answer.Contains("paint_name")) && (!answer.Contains("not"))) resolve = true;
                if ((ask.Contains("find_art")) && (answer.Contains("art_name")) && (!answer.Contains("not"))) resolve = true;
                if ((ask.Contains("issue")) && ((answer.Contains("find_art")) || (answer.Contains("find_paint"))) && (!answer.Contains("not"))) resolve = true;
            }
            return resolve;
        }

        public static string combine(string answer, string ask)
        {
            return answer;
        }

        public static string plan(string ask)
        { 
            string plan_name="";
            if (ask.Contains("find_art")) plan_name = "plan_find_art";
            if (ask.Contains("find_paint")) plan_name = "plan_find_paint";
            return plan_name;
            // neu ="" tuc la ko co plan thoa man
        }

        public static int COM_total(string[] COM)
        {
            bool stop = false;
            int i = 0;
            int total = 0;
            while ((stop == false)&&(i< COM.Length))
            {
                if (COM[i] != null)
                {
                    total++;
                    i++;
                }
                else stop = true;
            }
            return total;
        
        }
  
    }

    public class grounding
    {
        public static void getLatestMove(action_move_define last_move, string last_speak, ref action_move_define MOVE, ref string SPEAKER)
        {
            MOVE.set_content(last_move.get_content()) ;
            MOVE.set_type(last_move.get_types()) ;
            SPEAKER = last_speak;
        }
    }

    public class Integrate
    {
        public  static void integrateSysAsk(action_move_define MOVE, string SPEAKER, ref Stack<string> QUD)
        {
            if ((SPEAKER == "sys") && (MOVE.get_types()=="ask"))
            {
                string q = MOVE.get_content();
                QUD.Push(q);
                
            }
        }

        public  static void integrateUsrAsk(action_move_define MOVE, string SPEAKER, ref Stack<string> QUD, ref Stack<action_move_define> AGENDA)
        {
            if ((SPEAKER == "usr") && (MOVE.get_types() == "ask"))
            {
                string q = MOVE.get_content();
                QUD.Push(q);
                action_move_define action = new action_move_define("respond", q);
                AGENDA.Push(action);
            }
        }

        public  static void integrateAnswer(action_move_define MOVE, Stack<string> QUD, ref string[] COM)
        {
            if (MOVE.get_types()=="answer")
            {
                string a= MOVE.get_content();
                if (QUD.Count > 0)
                {
                    string q = QUD.Peek();
                    if (QA_issue.relevant(a, q))
                    {
                        string p = QA_issue.combine(a, q);
                        COM[QA_issue.COM_total(COM)] = p;
                    }
                }
            }
        }

        public  static void integrateUsrQuit(action_move_define MOVE, string SPEAKER, ref Stack<action_move_define> AGENDA)
        {
            if ((MOVE.get_types() == "quit") && (SPEAKER == "usr"))
            {
                action_move_define action = new action_move_define("quit");
                AGENDA.Push(action);
            }
        }

        public  static void integrateSysQuit(action_move_define MOVE, string SPEAKER, ref string program_state)
        {
            if ((MOVE.get_types() == "quit") && (SPEAKER == "sys"))
                program_state = "quit";
        }

        public static void integrateUsrGreet(action_move_define MOVE, string SPEAKER, ref Stack<action_move_define> AGENDA)
        {
            if ((MOVE.get_types() == "greet1") && (SPEAKER == "usr"))
            {
                action_move_define action = new action_move_define("greet1");
                AGENDA.Push(action);
            }
        }
    }

    public class DowndateQUD
    {
        public static void downdateQUD1(ref Stack<string> QUD, string[] COM)
        {
            if (QUD.Count > 0)
            {
                string q = QUD.Peek();
                bool stop = false;
                int i = 0;
                while ((stop == false) && (i < QA_issue.COM_total(COM)))
                {
                    if (QA_issue.resolves(COM[i], q)) //   if (QA_issue.relevant(COM[i], q))//
                    { stop = true; QUD.Pop(); }
                    else i++;
                }
            }
        }

        public static void downdateQUD(ref Stack<string> QUD, string[] COM)
        {
            if (QUD.Count > 0)
            {
                int j = QUD.Count;
                DowndateQUD.downdateQUD1(ref QUD, COM);
                while(j != QUD.Count)
                {
                    j = QUD.Count;
                    DowndateQUD.downdateQUD1(ref QUD, COM);
                }
              
            }
        }

        public static void downdataQUD2(ref Stack<string> QUD)
        { 
            // chua viet, chua su dung den
        
        }
    }

  
    /// <summary>
    /// /
    /// </summary>
    public class FindPlan
    {
        public static void findPlan(ref Stack<action_move_define> AGENDA, string[] BEL, ref Stack<action_move_define> PLAN,  Stack<action_move_define> plan_paint, Stack<action_move_define> plan_art)
        {
            if (AGENDA.Count > 0)
            {
                action_move_define agenda_top_action = AGENDA.Peek();
                if (agenda_top_action.get_types()=="respond")
                {
                    string q = agenda_top_action.get_content();
                    string plan_name = QA_issue.plan(q);
                    if (plan_name != "")
                    {
                        bool not_resolve = true;
                        bool stop = false; int i = 0;
                        while ((stop == false) && (i < QA_issue.COM_total(BEL)))
                        {
                            if (QA_issue.resolves(BEL[i], q)) { stop = true; not_resolve = false; }
                            else i++;

                        }

                        if (not_resolve == true)
                        {
                            AGENDA.Pop();
                            if (plan_name.Contains("art"))
                                {
                                    while (plan_art.Count > 0)
                                    {
                                        action_move_define temp = plan_art.Pop();
                                        PLAN.Push(temp);
                                    }

                                }
                                else
                                {
                                    while (plan_paint.Count > 0)
                                    {
                                        action_move_define temp = plan_paint.Pop();
                                        PLAN.Push(temp);
                                    }
                                }
                            
                        }
                    }

                }
            }
        }
    }

    public class ExecutePlan
    {
        public static void removeFindout(ref Stack<action_move_define> PLAN, string[] COM)
        {
            if (PLAN.Count > 0)
            {
                action_move_define plan_top = PLAN.Peek();
                if (plan_top.get_types ()=="findout")
                {
                    string q = plan_top.get_content();
                    bool not_resolve = true;
                    bool stop = false; int i = 0;
                    while ((stop == false) && (i < QA_issue.COM_total(COM)))
                    {
                        if (QA_issue.resolves(COM[i], q)) { stop = true; not_resolve = false; }
                        else i++;

                    }
                    if (not_resolve == false) PLAN.Pop();
                }
            }
        }


        public static void exec_consultDB_find_art(string[] COM, ref string[] BEL)
        {
            string have_paint = "";
            string nationality = "";

            for (int i = 0; i < QA_issue.COM_total(COM); i++)
            {
                if (COM[i].Contains("?.have_paint")) have_paint = COM[i].Replace("?.have_paint.","");
                if (COM[i].Contains("?.nationality")) nationality = COM[i].Replace("?.nationality.","");
            }
            if (have_paint != "")
            {
                //string connString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\QASys.mdf;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True";
                try
                {
                    string queryString = "";
                    //SqlConnection conn = new SqlConnection(connString);
                    //conn.Open();
                    if (nationality == "")
                        queryString = "SELECT * FROM ARTIST A, PAINT P WHERE ((P.Art_Id=A.Art_Id) AND (P.Name LIKE N'%" + have_paint + "%'))";
                    else queryString = "SELECT * FROM ARTIST A, PAINT P WHERE ((P.Art_Id=A.Art_Id) AND (P.Name LIKE N'%" + have_paint + "%')AND (A.Nationality LIKE N'%" + nationality + "%'))";
                    DataTable dt = new DataTable();
                    SqlDataAdapter da = new SqlDataAdapter(queryString, MainWindow.DBConnection);
                    da.Fill(dt);
                    //try
                    //{
                    //    conn.Close();
                    //}
                    //catch (Exception e)
                    //{
                    //    throw (e);
                    //}
                    if (dt.Rows.Count == 0)
                    { BEL[QA_issue.COM_total(BEL)] = "art_name.0"; }
                    else
                    {

                        BEL[QA_issue.COM_total(BEL)] = "art_name." + dt.Rows[0]["Name"].ToString() + ".";


                    }
                }
                catch (Exception ex)
                {
                   
                    throw (ex);
                }
            }
            else
            { BEL[QA_issue.COM_total(BEL)] = "art_name.Chương trình lỗi."; }
        }

        public static void exec_consultDB_find_paint(string[] COM, ref string[] BEL)
        {
            string genre = "";
            string artist = "";
            string material = "";

            for (int i = 0; i < QA_issue.COM_total(COM); i++)
            {
                if (COM[i].Contains("?.genre")) genre = COM[i].Replace("?.genre.", "").ToLower();
                if (COM[i].Contains("?.artist")) artist = COM[i].Replace("?.artist.","").ToUpper(); ;
                if (COM[i].Contains("?.material")) material = COM[i].Replace("?.material.","").ToLower();

            }
            if ((genre != "")&&(artist!=""))
            {
                //string connString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\QASys.mdf;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True";
                try
                {
                    string queryString = "";
                    //SqlConnection conn = new SqlConnection(connString);
                    //conn.Open();
                    if (material == "")
                        queryString = "SELECT * FROM PAINT P,ARTIST A, PAINT P, GENRE G WHERE ((P.Art_Id=A.Art_Id) AND (P.Gen_Id=G.Gen_Id) AND (A.Name LIKE N'%" + artist + "%') AND ( G.Kind LIKE N'%" + genre + "%'))";
                    else queryString = "SELECT * FROM PAINT P,ARTIST A,  GENRE G WHERE ((P.Art_Id=A.Art_Id) AND (P.Gen_Id=G.Gen_Id) AND (A.Name LIKE N'%" + artist + "%') AND ( G.Kind LIKE N'%" + genre + "%')AND (P.Material LIKE N'%" + material + "%'))";
                    DataTable dt = new DataTable();
                    SqlDataAdapter da = new SqlDataAdapter(queryString, MainWindow.DBConnection);
                    da.Fill(dt);
                    //try
                    //{
                    //    conn.Close();
                    //}
                    //catch (Exception e)
                    //{
                    //    throw (e);
                    //}
                
                    if (dt.Rows.Count == 0)
                      { BEL[QA_issue.COM_total(BEL)] = "paint_name.0"; }
                    else
                    {
                        string consultDB_paint = "paint_name.";
                       
                        for (int i = 0; i < dt.Rows.Count; i++)
                        {

                            if (i != (dt.Rows.Count - 1)) consultDB_paint += dt.Rows[i]["Name"].ToString() + ", ";
                            else consultDB_paint += dt.Rows[i]["Name"].ToString()+".";

                        }
                        BEL[QA_issue.COM_total(BEL)] = consultDB_paint;
                    }
                     
                }
                catch (Exception ex)
                {
                  
                    throw (ex);
                }
            }
            else
            { BEL[QA_issue.COM_total(BEL)] = "paint_name.Chương trình lỗi."; }
        }
        
        public static void exec_consultDB(ref Stack<action_move_define> PLAN, string[] COM, ref string[] BEL)
        {
            if (PLAN.Count > 0)
            {
                action_move_define top_plan = PLAN.Peek();
                if (top_plan.get_types() == "consultDB")
                {
                    string q = top_plan.get_content();
                    //LastestQues.Items.Add(q);
                    if (q.Contains("paint")) { ExecutePlan.exec_consultDB_find_paint(COM, ref BEL); PLAN.Pop(); }
                    else { ExecutePlan.exec_consultDB_find_art(COM, ref BEL); PLAN.Pop(); }

                }

            }

            /*
            if (PLAN.Count > 0)
            {
                action_move_define top_plan = PLAN.Peek();
                if (top_plan.get_types()=="consult")
                {
                    if (QA_issue.COM_total(COM) > 0)
                    {
                        string q = top_plan.get_content();
                        if (q.Contains("find_art"))
                        {
                            exec_plan.exec_consultDB_find_art(COM, ref BEL);
                            PLAN.Pop();
                        }
                        else
                        {
                            if (q.Contains("find_paint"))
                            {
                                exec_plan.exec_consultDB_find_paint(COM, ref BEL);
                                PLAN.Pop();
                            }
                        }
                    }
                }
            }
             */

        }

        public static void recoverPlan(Stack<string> QUD, Stack<action_move_define> AGENDA, ref  Stack<action_move_define> PLAN,  Stack<action_move_define> plan_paint, Stack<action_move_define> plan_art)
        {
            if ((AGENDA.Count == 0) && (PLAN.Count == 0) && (QUD.Count > 0))
            {
                string q = QUD.Peek();
                string plan_name = QA_issue.plan(q);
                if (plan_name != "")
                {
                        if (plan_name.Contains("art"))
                        {
                            while (plan_art.Count > 0)
                            {
                                action_move_define temp = plan_art.Pop();
                                PLAN.Push(temp);
                            }

                        }
                        else
                        {
                            while (plan_paint.Count > 0)
                            {
                                action_move_define temp = plan_paint.Pop();
                                PLAN.Push(temp);
                            }
                        }
                    
                }

            }
        }

        public static void removeRaise(ref Stack<action_move_define> PLAN, string[] COM)
        {
            if (PLAN.Count > 0)
            {
                action_move_define top_plan = PLAN.Peek();
                if (top_plan.get_types()=="raise")
                {
                    string q= top_plan.get_content();
                    bool stop = false;
                    int i = 0;
                    while (stop == false)
                    {
                        if (QA_issue.resolves(COM[i], q)) { stop = true; PLAN.Pop(); }
                        else
                        {
                            i++; 
                            if (i == QA_issue.COM_total(COM)) stop = true;
                        }
                    }
                }
            }
        }
    }


    public class select_action
    { 
   
        public static void selectFromPlan(ref Stack<action_move_define> AGENDA, Stack<action_move_define> PLAN)
       {
        if ((AGENDA.Count == 0) && (PLAN.Count > 0))
        {
            action_move_define action = PLAN.Peek();
            AGENDA.Push(action);
        }
       }

        public static bool not_in(string t, string[] array_t)
        { 
             bool not_in_array= true;
             bool stop = false;
             int i = 0;
             while ((stop == false) && (i < QA_issue.COM_total(array_t)))
             {
                 if (t == array_t[i]) { stop = true; not_in_array = false; }
                 else i++;
             }
             return not_in_array;
           
        }

        public static void selectRespond(Stack<string> QUD, Stack<action_move_define> AGENDA, ref Stack<action_move_define> PLAN, string[] BEL, string[] COM)
        {
            if ((AGENDA.Count == 0) && (PLAN.Count == 0))
            {
                if (QUD.Count > 0)
                {
                    string q = QUD.Peek();
                    int i = 0;
                    bool stop = false;
                    while (stop == false)
                    {
                    if ((select_action.not_in(BEL[i],COM))&&(QA_issue.relevant(BEL[i],q)))
                    {
                        action_move_define action = new action_move_define("respond", q);
                        AGENDA.Push(action);
                        stop=true;
                    }
                        else
                    {
                        i++; if (i==QA_issue.COM_total(BEL)) stop=true;
                    }
                    }


                }
            }
        }


        public static void reraiseIssue()
        { 
        //chua viet
        }
    }

    public class select_move
    { 
     public static void selectAsk(Stack<action_move_define> AGENDA,ref action_move_define next_move, ref Stack<action_move_define> PLAN)
     {
         if (AGENDA.Count > 0)
         {
             action_move_define top_agenda = AGENDA.Peek();
             if (top_agenda.get_types()=="findout")
             {
                 string q = top_agenda.get_content();
                 next_move.set_type("ask");
                 next_move.set_content(q);
             }
             if (top_agenda.get_types()=="raise")
             {
                 string q = top_agenda.get_content();
                 next_move.set_type("ask");
                 next_move.set_content(q);
                 PLAN.Pop();

             }
         }
     }

     public static void selectAnswer(Stack<action_move_define> AGENDA, ref action_move_define next_move, string[] BEL, string[] COM)
     {
         if (AGENDA.Count > 0)
         {
             action_move_define top_agenda = AGENDA.Peek();
             if (top_agenda.get_types()=="respond")
             {
                 string q = top_agenda.get_content();
                 int i = 0;
                    bool stop = false;
                    while (stop ==false)
                    {
                    if ((select_action.not_in(BEL[i],COM))&&(QA_issue.relevant(BEL[i],q)))
                    {
                        
                        next_move.set_content(BEL[i]);
                        next_move.set_type("answer");
                        stop=true;
                    }
                        else
                    {
                        i++; if (i==QA_issue.COM_total(BEL)) stop=true;
                    }
                    }
             }
         }
     
     }
    
    }
     public class select_other
        
     {
         public static void selectOther (Stack<action_move_define> AGENDA,ref action_move_define next_move)
         {
         if (AGENDA.Count>0)
         {
             action_move_define move= AGENDA.Peek();
             if ((move.get_types() == "ask") || (move.get_types() == "answer") || (move.get_types() == "quit") || (move.get_types() == "greet") || (move.get_types() == "greet1"))
             next_move=AGENDA.Pop();
         }
         }
     }

    public class module
    {
        public static string generatemodule(action_move_define nextmmove)
        { 
            string output="";
        if (nextmmove.get_types()=="ask")
        {
            if (nextmmove.get_content().Contains("genre")) output = "Bạn muốn tìm tranh thuộc trường phái nào?";
            if (nextmmove.get_content().Contains("material")) output = "Bạn muốn tìm tranh vẽ trên chất liệu nào?";
            if (nextmmove.get_content().Contains("artist")) output = "Bạn muốn tìm tranh của tác giả nào nào?";
            if (nextmmove.get_content().Contains("have_paint")) output = "Kể tên một bức tranh của họa sĩ?";
            if (nextmmove.get_content().Contains("nationality")) output ="Họa sĩ bạn muốn tìm là người nước nào?";
        }
        if (nextmmove.get_types()=="answer")
        {
            if (nextmmove.get_content().Contains("art_name")) 
            {
                string t = nextmmove.get_content().Replace("art_name.", "");
                if (t == "0") output = "Không tìm được họa sĩ như bạn mô tả.";
                else output = "Họa sĩ đó là "+ t+".";
               
            }
            if (nextmmove.get_content().Contains("paint_name"))
            {
                string t = nextmmove.get_content().Replace("paint_name.", "");
                if (t == "0") output = "Không tìm được tranh như bạn mô tả.";
                else  output = "Tranh tìm được là "+t+".";
            }
        }
        if (nextmmove.get_types()=="greet") output = "Chào bạn.";
        if (nextmmove.get_types()=="quit") output = "Tạm biệt.";
        if (nextmmove.get_types() == "greet1") output = "xin mời bạn đặt câu hỏi.";
        
            
            return output;
        }

        public static void inputmodule(string user_text,ref string last_speak, ref action_move_define last_move)
        {
            if (user_text != "")
            {
                QA_issue.interpret_user(user_text, ref last_speak, ref last_move);
            }
           
        }
        
      
        
        
        public static string outputmodule(string sys_text,ref action_move_define next_move ,ref string last_speak, ref action_move_define last_move)
        {
            if (sys_text != "")
            {
                last_speak = "sys";
                last_move.set_content(next_move.get_content());
                last_move.set_type(next_move.get_types());
                next_move.set_type("");
                next_move.set_content("");
                
            }
            return sys_text;
        }

        public static void updatemodule(action_move_define last_move,string last_speaker,ref string program_state,ref action_move_define next_move,ref Stack<action_move_define> AGENDA, ref Stack<action_move_define> PLAN ,ref string[] BEL, ref string[] COM,ref Stack<string> QUD,ref string SPEAKER,ref action_move_define MOVE, Stack<action_move_define> plan_art, Stack<action_move_define> plan_paint)
        {
            if (last_move.get_types()!="fail")
            {
                AGENDA.Clear();
                grounding.getLatestMove(last_move,last_speaker, ref MOVE, ref SPEAKER);
                Integrate.integrateUsrGreet(MOVE, SPEAKER, ref AGENDA);
                Integrate.integrateAnswer(MOVE,QUD,ref COM);
                Integrate.integrateSysAsk(MOVE, SPEAKER, ref QUD);
                Integrate.integrateSysQuit(MOVE, SPEAKER,ref  program_state);
                Integrate.integrateUsrAsk(MOVE, SPEAKER, ref QUD, ref AGENDA);
                Integrate.integrateUsrQuit(MOVE, SPEAKER, ref AGENDA);
                DowndateQUD.downdateQUD(ref QUD, COM);
                FindPlan.findPlan(ref AGENDA, BEL, ref PLAN, plan_paint, plan_art);
                ExecutePlan.removeFindout(ref PLAN, COM);
                ExecutePlan.exec_consultDB(ref PLAN, COM,ref BEL);
            }

        }

        public static void selectmodule(ref action_move_define next_move, ref Stack<action_move_define> AGENDA, ref Stack<action_move_define> PLAN, ref string[] BEL, ref string[] COM, ref Stack<string> QUD)
    {
        
        select_action.selectFromPlan(ref AGENDA, PLAN);
        select_action.selectRespond(QUD, AGENDA, ref PLAN, BEL, COM);
        //select_action.reraiseIssue();
        select_move.selectAnswer(AGENDA, ref next_move, BEL, COM);
        select_move.selectAsk(AGENDA, ref next_move, ref PLAN);
        select_other.selectOther(AGENDA, ref next_move);
    }
    }
}
